<?php

namespace app\common\model;

//美团功能
use app\admin\model\MeituanAuth;

class MeituanLogic
{

    //HTTP POST 方法统一使用contentType 为“application/x-www-form-urlencoded”
    private static $contentType = "application/x-www-form-urlencoded";


    /**
     * 获取美团商家授权URL
     * @param $app_key 应用key
     * @param $redirect_uri 重定向地址
     * @param $state 自定义的数据
     * @return string
     */
    public static function GetAuthUrl($app_key, $redirect_uri, $state)
    {
        //https://e.dianping.com/dz-open/merchant/auth?app_key=f9e039e3da9ea9ec&redirect_url=https://cn.bing.com&state=teststate&scope=[%22tuangou%22,%22ugc%22]
        $url = "https://e.dianping.com/dz-open/merchant/auth?app_key=" . $app_key . "&redirect_url=" . $redirect_uri . "&state=" . $state . "&scope=";
        return $url;
    }


    /**
     * 获取美团商家授权token
     * @param $app_key 应用key
     * @param $app_secret 应用密钥
     * @param $auth_code 授权码
     * @param $state 自定义的数据
     * 请求地址:
     * https://openapi.dianping.com/router/oauth/token
     * 请求参数:
     * app_key    string    是
     * app_secret    string    是
     * auth_code    string    是    获取session的授权码
     * grant_type    string    是    填 authorization_code
     * redirect_url    string    否    获取授权码的回调地址
     * 说明：接入授权UI过程中
     * 当通过回调地址获取授权码时，该参数必填（与调用授权UI组件时的回调地址一致）
     * 当通过监听window消息获取授权码时，该参数不要填
     *即该参数是否填写与调用授权UI组件时是否填写了回调地址直接相关
     * 返回说明:
     * access_token    string    是    即为session
     * expires_in    long    是    过期时间,秒，如10000秒之后过期
     * scope    string    是    session的权限范围，对应模块名称
     * refresh_token    string    是    即为refresh_session，授权可刷新次数用完后，将不再返回新的refresh_session
     * remain_refresh_count    int    是    剩余刷新次数
     * bid    string    是    客户Id，注：bid不是open_shop_uuid
     * tokenType    String    是    返回bearer
     * code    int    是    返回code
     * msg    string    否    提示信息
     * 返回示范:
     * {
     * "access_token":"6b53c12aadbe71b150a1a0c4958fabcd69daf52e",
     * "expires_in":2591998,
     * "tokenType":"bearer",
     * "scope":"tuangou,ugc,poi,shopping,,merchant_data",
     * "refresh_token":"cb9023ebe8aae27592a446aa41978b78032e3435",
     * "bid":"a12312b2312c",
     * "code":200,
     * "msg":null
     * }
     */
    public static function GetAuthToken($app_key, $app_secret, $auth_code, $state, $redirect_uri)
    {
        //使用fastadmin的http请求类 admin/extend/fast/Http.php
        $http = new \fast\Http();
        $url = "https://openapi.dianping.com/router/oauth/token";
        $params = [
            'app_key'      => $app_key,
            'app_secret'   => $app_secret,
            'auth_code'    => $auth_code,
            'grant_type'   => 'authorization_code',
            'redirect_url' => $redirect_uri,
            'state'        => $state,
        ];

        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $result = $http->post($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        return $result;
    }


    /*
     * session适用门店列表查询
     * 接口路径	https://openapi.dianping.com/router/oauth/session/scope
     * 调用方法	HTTP GET
     * 参数名称	参数类型	是否必须	参数描述	是否参与加签
        app_key	String	是	北极星到综开放平台分配给应用的AppKey。	是
        sign_method	String	是	签名的摘要算法，默认值为：MD5。	是
        timestamp	String	是	时间戳，格式为yyyy-MM-dd HH:mm:ss，时区为GMT+8，例如：2017-01-01 12:00:00。服务端允许客户端请求最大时间误差为30分钟。	是
        v	String	是	API协议版本，默认值：1，此后版本升级，会递增。	是
        sign	String	是	API输入参数签名结果。
        format	string	是	响应格式。默认为json格式	是
        session	String	是	session值	是
        bid	String	是	客户的唯一标识，通过session换取/刷新接口	是
        offset	int	否	分页查询，从第几条记录开始获取。下标从0开始，最大不超过3000	是
        limit	int	否	分页查询，每页返回多少条记录。最大返回300条 是
     * 返回说明:
     * 字段	类型	必选	说明
        data	json array	是	返回适用门店列表范围
        code	Integer
        状态码
        msg	String

        data详细结构体：

        字段	类型	必选	说明
        open_shop_uuid	String	是	门店id的唯一标识
        shopname	String	是	门店名称
        branchname	String	否	分店名称
                       shopaddress	String	是	门店地址
        cityname	String	是	所在城市
     * 返回示范:
     * {
        "data": [{
                "open_shop_uuid": "e29b7e5c98cb9a11d608152b2c77ccdd",
                "shopname": "Forgot Bar",
                "branchname": "",
                "shopaddress": "将台西路上东8号底商129号",
                        "cityname":"上海"
            }, {
                "open_shop_uuid": "f6c1b5db84390eb0bf62482c429ee9c1",
                "shopname": "好乐迪",
                "branchname": "中山公园店",
                "shopaddress": "长宁路999号多媒体生活广场4楼",
                        "cityname":"上海"
            }],
        "code": 200,
        "msg": "success"
        }
     */
    public static function getShopList($app_key, $app_secret, $session, $bid)
    {
        //使用fastadmin的http请求类 admin/extend/fast/Http.php
        $http = new \fast\Http();
        $url = "https://openapi.dianping.com/router/oauth/session/scope";
        $params = [
            'app_key'     => $app_key,
            'sign_method' => 'MD5',
            'timestamp'   => date('Y-m-d H:i:s'),
            'v'           => '1',
            'format'      => 'json',
            'session'     => $session,
            'bid'         => $bid,
            'offset'      => '0',
            'limit'       => '300',
        ];
        $params['sign'] = self::getSign($app_secret, $params);
        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $result = $http->get($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        $result = json_decode($result, true);
        return $result;
    }


    /**
     * 计算签名
     *
     * @param $app_secret 三方app_secret
     * @param $req_param 请求参数集合，包括公共参数和业务参数
     * @return string md5签名
     */
    private static function getSign($app_secret, $req_param)
    {
        // 排序所有请求参数
        ksort($req_param);
        $src_value = "";
        // 按照key1value1key2value2...keynvaluen拼接
        foreach ($req_param as $key => $value) {
            $src_value .= ($key . $value);
        }
        //计算md5
        return md5($app_secret . $src_value . $app_secret);
    }


    /*
     * session刷新
     * 接口路径	https://openapi.dianping.com/router/oauth/token
     * 调用方法	HTTP POST
     * 返回参数:
     * access_token	string	是	即为session
expires_in	long	是	过期时间,秒，如10000秒之后过期
scope	string	是	session的权限范围，对应模块名称
refresh_token	string	是	即为refresh_session，授权可刷新次数用完后，将不再返回新的refresh_session
remain_refresh_count	int	是	剩余刷新次数
bid	string	是	客户Id
code	int	是	返回code
msg	string	否	提示信息
     */
    public static function RefreshSession($app_key, $app_secret, $refresh_token)
    {
        $url = "https://openapi.dianping.com/router/oauth/token";
        $params = [
            'app_key'       => $app_key,
            'app_secret'    => $app_secret,
            'grant_type'    => 'refresh_token',
            'refresh_token' => $refresh_token,
        ];
        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $http = new \fast\Http();
        $result = $http->post($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        $result = json_decode($result, true);
        if ($result['code'] != 200) {
            return $result;
        }
        $expire_time = time() + $result['expires_in'];
        //过期时间戳转换为日期
        $session_expire_time = date('Y-m-d H:i:s', $expire_time);
        $update_data = [
            'scope'                => $result['scope'],
            'refresh_session'      => $result['refresh_token'],
            'session'              => $result['access_token'],
            'remain_refresh_count' => $result['remain_refresh_count'],
            'bid'                  => $result['bid'],
            'session_expire_time'  => $session_expire_time,
            'session_status'       => 1,
            'last_refresh_time'    => date('Y-m-d H:i:s'),
            'log_info'             => $result['msg'],
        ];
        MeituanAuth::where('app_key', $app_key)->where('app_secret', $app_secret)->where(
            'refresh_session',
            $refresh_token
        )->update($update_data);
        return $result;
    }

    //获取公共参数
    public static function GetPublicParams($app_key, $session)
    {
        $params = [
            'app_key'     => $app_key,
            'timestamp'   => date('Y-m-d H:i:s'),
            'format'      => 'json',
            'v'           => '1',
            'sign_method' => 'MD5',
            'session'     => $session,
        ];
        return $params;
    }


    /*
     * 查询门店消费码商品信息
     * 接口路径url        	https://openapi.dianping.com/router/tuangou/product/queryproduct
     */
    public static function QueryProduct($app_key, $app_secret, $session, $open_shop_uuid)
    {
        $url = "https://openapi.dianping.com/router/tuangou/product/queryproduct";
        $params = self::GetPublicParams($app_key, $session);
        // $params = $params + ['open_shop_uuid' => $open_shop_uuid,];
        $params = array_merge($params,['open_shop_uuid' => $open_shop_uuid,]);
        $params['sign'] = self::getSign($app_secret, $params);
        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $http = new \fast\Http();
        $result = $http->get($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        $result = json_decode($result, true);
        return $result;
    }

    /*
     * 输码验券校验接口
     * 文档地址: https://open.dianping.com/document/v2?docId=6000843&rootDocId=5000
     * 接口地址: https://openapi.dianping.com/router/tuangou/receipt/prepare
     * receipt_code	string	是	团购券码，必须未验证
     * open_shop_uuid	string	是 美团点评店铺id，必须是团购的适用门店，关于open_shop_uuid的介绍可以参考文档：open_shop_uuid相关问题
     * 返回参数:
     *  count	int	是	可验证的张数
        receipt_code	string	是	验证券码
        deal_id	long	否	套餐id（若验证的券所对应的商品为团购时，该字段必返回）
        dealgroup_id	long	否	团购id,团购id与套餐id是一对多的关系（若验证的券所对应的商品为团购时，该字段必返回）
        product_item_id	long	否	商品id（若验证的券所对应的商品非团购时，该字段必返回，product_item_id含义参考商品管理API）
        product_type	int	否	商品类型 1、泛商品如丽人派样活动商品等（若验证的券所对应的商品非团购时，该字段必返回）
        deal_title	string	是	商品名称
        deal_price	double	否	商品售卖价格
        deal_marketprice	double	否	商品市场价
        biz_type	int	是	业务类型 0:普通团购 205:次卡
        receiptEndDate

        Date	是	券过期时间
        payment_detail	List<PaymentDetailDTO>
        是	支付明细
        mobile	string	否	用户手机号	形如:185****1212
        receipt_info_map	Map<Long, List<ReceiptValidateResultDTO>	否
        多团单维度券信息，如果为null则为单团单,key为product_item_id

        {
        "code": 1,
        "msg": "美团团购券信息",
        "time": "1679909566",
        "data": {
        "count": 1,  //团购券可用张数
        "receipt_code": "2306434509",
        "deal_id": 943017524,
        "dealgroup_id": 776306224, //团购ID
        "deal_title": "60分钟足部足疗", //团购商品名称
        "deal_price": 1, //实际售卖价
        "deal_marketprice": 120, //市场价
        "mobile": "180****3089",
        "product_type": null,
        "product_item_id": null,
        "biz_type": 0,  //业务类型 0:普通团购 205:次卡
        "payment_detail": [
        {
        "payment_detail_id": "49089458374163761471M9P50101",
        "amount": 1,
        "amount_type": 10
        }
        ],
        "receipt_info_map": null,
        "receiptEndDate": 1687708799000
        }
        }
     */
    public static function ReceiptPrepare($app_key, $app_secret, $session, $receipt_code, $open_shop_uuid){
        $url = "https://openapi.dianping.com/router/tuangou/receipt/prepare";
        $params = self::GetPublicParams($app_key, $session);
        $params = array_merge($params,['receipt_code' => $receipt_code,'open_shop_uuid' => $open_shop_uuid,]);
        $params['sign'] = self::getSign($app_secret, $params);
        // halt($params);
        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $http = new \fast\Http();
        $result = $http->get($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        $result = json_decode($result, true);
        return $result;
    }


    /*
     * 输码验券校验接口
     * 文档: https://open.dianping.com/document/v2?docId=6000844&rootDocId=5000
     *  https://openapi.dianping.com/router/tuangou/receipt/scanprepare
     * qr_code	string	是	二维码对应code
     * open_shop_uuid	string	是 美团点评店铺id，必须是团购的适用门店，关于open_shop_uuid的介绍可以参考文档：open_shop_uuid相关问题
     */
    public static function ReceiptScanprepare($app_key, $app_secret, $session, $qr_code, $open_shop_uuid){
        $url = "https://openapi.dianping.com/router/tuangou/receipt/prepare";
        $params = self::GetPublicParams($app_key, $session);
        $params = array_merge($params,['qr_code' => $qr_code,'open_shop_uuid' => $open_shop_uuid,]);
        $params['sign'] = self::getSign($app_secret, $params);
        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $http = new \fast\Http();
        $result = $http->get($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        $result = json_decode($result, true);
        return $result;
    }

    /*
     * 确定验券接口
     * 文档: https://open.dianping.com/document/v2?docId=6000846&rootDocId=5000
     * https://openapi.dianping.com/router/tuangou/receipt/consume
     * 参数如下:
     *  requestid	string	是	请求id，用于标识幂等性
        receipt_code	string	是	团购券码，必须未验证
        count	int	是	验券数量, 不可多于100个
        open_shop_uuid	string	是
        美团点评店铺id，必须是团购的适用门店，关于open_shop_uuid的介绍可以参考文档:open_shop_uuid相关问题
        app_shop_account	string	是	商家在自研系统或第三方服务商系统内登录的帐号，仅用于记录验券者的信息，该字段不参与任何验券校验逻辑
        app_shop_accountname	string	是	商家在自研系统或第三方服务商系统内登陆的用户名，仅用于记录验券者的信息，该字段不参与任何验券校验逻辑
    */
    public static function ReceiptConsume($app_key, $app_secret, $session, $requestid, $receipt_code, $count, $open_shop_uuid, $app_shop_account, $app_shop_accountname){
        $url = "https://openapi.dianping.com/router/tuangou/receipt/consume";
        $params = self::GetPublicParams($app_key, $session);
        $params = array_merge($params,[
            'requestid' => $requestid,
            'receipt_code' => $receipt_code,
            'count' => $count,
            'open_shop_uuid' => $open_shop_uuid,
            'app_shop_account' => $app_shop_account,
            'app_shop_accountname' => $app_shop_accountname,
        ]);
        $params['sign'] = self::getSign($app_secret, $params);
        $headers = [
            'Content-Type' => self::$contentType,
        ];
        $http = new \fast\Http();
        $result = $http->get($url, $params, [CURLOPT_HTTPHEADER => $headers]);
        $result = json_decode($result, true);
        return $result;
    }


}